<template>
  <div class="advert-campaign-wrap table-gl-w">
    <a-tabs v-model:active-key="activeTab" @change="changeActiveTab" size="mini">
      <a-tab-pane key="portfolio" title="广告组合" />
      <a-tab-pane key="campaign" title="广告活动" />
      <a-tab-pane key="targeting" title="自动投放" />
      <a-tab-pane key="searchWord" title="搜索词" />
      <a-tab-pane key="negativeKeyword" title="否定关键词" />
    </a-tabs>
    <template v-if="activeTab == 'portfolio' || activeTab == 'campaign'">
      <div class="search-w table-filter-form">
        <div class="filter-list flex-c">
          <template v-for="(item, i) in filterItem" :key="i">
            <div class="filter-item">
              <template v-if="item.type == 'input_keyword'">
                <filterKeyword :currentItem="item" @search="searchKeyword($event, item)" />
              </template>
              <template v-else-if="item.key == 'portfolioIds'">
                <portfolioIdsMultiple :key="item.key" :info="item" :defaultVal="item.value" @change="selectMulVal($event, item)" />
              </template>
              <template v-else-if="item.type == 'select_multiple'">
                <selectMultiple :key="item.key" :info="item" :defaultVal="item.value" :resultTags="resultTags" @change="selectMulVal($event, item)" />
              </template>
              <template v-else-if="item.type == 'select'">
                <a-select v-model="item.value" :style="{ width: item.width + 'px' }" :placeholder="item.placeholder || item.label" allow-clear @change="setSearchVal">
                  <a-option v-for="(option, s) in item.optionItems" :key="s" :value="option.value" :label="option.label" />
                </a-select>
              </template>
              <template v-else-if="item.type == 'date_range'">
                <a-range-picker v-model="item.value" :="item.attrs" :disabledDate="disabledDate" :style="{ width: item.width + 'px' }" :allow-clear="false" shortcuts-position="left" :shortcuts="rangeShortcuts()" @change="setSearchVal" />
              </template>
            </div>
          </template>
          <!-- 气泡 -->
          <a-popover trigger="click" ref="selectMulRef" position="bottom" @popup-visible-change="popupVisibleChange">
            <template #content>
              <ul class="target-filter-w">
                <li class="flex-c" v-for="(item, i) in extendMetricsSearches" :key="i">
                  <span class="label">{{ AdTargetKeys[item.field] }}：</span>
                  <a-input-number v-model="item.minValue" style="width: 120px" placeholder="请输入" size="small">
                    <template #suffix>
                      <span class="unit">{{ item.unit }}</span>
                    </template>
                  </a-input-number>
                  <span class="line">—</span>
                  <a-input-number v-model="item.maxValue" style="width: 120px" placeholder="请输入" size="small">
                    <template #suffix>
                      <span class="unit">{{ item.unit }}</span>
                    </template>
                  </a-input-number>
                </li>
              </ul>
              <div class="flex-c-end" style="margin-top: 20px">
                <a-space>
                  <a-button size="mini" @click="closePopover">取消</a-button>
                  <a-button type="primary" size="mini" @click="setTargetFilter">确认</a-button>
                </a-space>
              </div>
            </template>
            <a-button class="gray-outline filter-item">
              <template #icon>
                <icon-filter />
              </template>
            </a-button>
          </a-popover>
          <div class="filter-item">
            <a-button @click="resetAll">重置</a-button>
          </div>
        </div>
        <div class="filter-result" v-show="resultTags.length > 0 || metricsSearchesReault.length > 0">
          <a-space wrap>
            <a-tag v-for="item in resultTags" size="small" color="arcoblue" closable :key="item.key" @close="delTag(item, 1)">
              <template v-if="!(item.tagVal instanceof Array && item.tagVal.length > 2)">
                <span> {{ item.label }}：</span>
                <p>{{ item.tagVal instanceof Array ? item.tagVal?.join(',') : item.tagVal }}</p>
              </template>
              <a-popover v-else position="bottom">
                <div class="flex-c">
                  <span> {{ item.label }}：</span>
                  <p>{{ item.tagVal[0] }}，{{ item.tagVal[1] }}等{{ item.tagVal.length }}项</p>
                </div>
                <template #content>
                  <p v-for="(val, j) in item.tagVal" :key="j">{{ val }}</p>
                </template>
              </a-popover>
            </a-tag>
            <a-tag v-for="item in metricsSearchesReault" size="small" color="arcoblue" closable :key="item.field" @close="delTag(item, 2)">
              <span> {{ AdTargetKeys[item.field] }}：</span>
              <p v-if="(item.minValue || item.minValue === 0) && (item.maxValue || item.maxValue === 0)">{{ item.minValue }}-{{ item.maxValue }}</p>
              <p v-else-if="item.minValue || item.minValue === 0">>={{ item.minValue }}</p>
              <p v-else>&lt;={{ item.maxValue }}</p>
            </a-tag>
            <a-button type="text" style="color: #000430" v-if="resultTags.length + metricsSearchesReault.length > 1" size="mini" @click="resetAll">清除全部</a-button>
          </a-space>
        </div>
      </div>
      <a-scrollbar style="flex: 1; overflow-y: auto; height: 100%" v-show="searchParam.startDate">
        <!-- 图表 -->
        <AdChart ref="adChartRef" :type="activeTab" :searchParams="searchParam" />
        <!-- 广告组合列表 -->
        <PortfolioTable v-if="activeTab == 'portfolio'" ref="portfolioTableRef" :markedtList="markedtList" :userList="userList" :shopList="shopList" :searchParams="searchParam" @toCampaign="toCampaign" />
        <!-- 广告活动列表 -->
        <CampaignTable v-if="activeTab == 'campaign'" ref="campaignTableRef" :markedtList="markedtList" :userList="userList" :shopList="shopList" :searchParams="searchParam" />
      </a-scrollbar>
      <div class="error-w" v-show="!searchParam.startDate">
        <a-empty> 数据量过大，请选择时间缩小查询范围 </a-empty>
      </div>
    </template>
    <!-- 搜索词 -->
    <SearchWordList v-if="activeTab == 'searchWord'" :markedtList="markedtList" @toCampaign="toCampaign" />
    <!-- 自动投放 -->
    <TargetingList v-if="activeTab == 'targeting'" :markedtList="markedtList" @toCampaign="toCampaign" />
    <!-- 否定关键词 -->
    <NegativeKeywordList v-if="activeTab == 'negativeKeyword'" :markedtList="markedtList" @toCampaign="toCampaign" />
  </div>
</template>
<script lang="ts">
  export default defineComponent({
    name: 'CampaignManagement',
  })
</script>
<script lang="ts" setup>
  import { ref, onMounted, nextTick, computed, defineComponent } from 'vue'
  import { FilterTableItem } from '@/types/components'
  import { getShopMarketAll, getOrganizesUser } from '@/api/system'
  import selectMultiple from '@/components/Form/selectMultiple.vue'
  import portfolioIdsMultiple from './components/portfolioIdsMultiple.vue'
  import PortfolioTable from './components/portfolioTable.vue'
  import CampaignTable from './components/campaignTable.vue'
  import AdChart from './components/adChart.vue'
  import { getStartAndEndTime, rangeShortcuts } from '../common'
  import { AdTargetKeys } from '../types'
  import SearchWordList from './searchWordList.vue'
  import TargetingList from './targetingList.vue'
  import NegativeKeywordList from './negativeKeywordList.vue'
  import useAdvertStore from '@/store/modules/advert'
  import useBaseDataStore from '@/store/modules/base-data'
  import dayjs from 'dayjs'

  onMounted(() => {
    getMarketList()
    getShopList()
    getUserList()
    changeActiveTab('portfolio')
  })

  const filterItem = computed(() => getFilterItem())
  // 指标范围过滤
  const extendMetricsSearches = ref<Array<any>>([{ field: 'impressions' }, { field: 'clicks' }, { field: 'ctr', unit: '%' }, { field: 'cost' }, { field: 'cpc' }, { field: 'purchasesOrder' }, { field: 'saleAmount' }, { field: 'cvr', unit: '%' }, { field: 'cpa' }, { field: 'acos', unit: '%' }, { field: 'roas' }])
  const activeTab = ref('portfolio')
  const userList = ref([])
  const markedtList = ref([])
  const shopList = ref<Array<any>>([])
  const resultTags = ref<any>([])
  const selectMulRef = ref()
  const searchParam = ref<any>({})
  const portfolioTableRef = ref()
  const campaignTableRef = ref()
  const adChartRef = ref()
  const metricsSearchesReault = ref<Array<any>>([])
  const advertStore = useAdvertStore()
  const useBaseData = useBaseDataStore()
  const allfilterItem = ref<Array<FilterTableItem>>([
    {
      key: 'marketplaceIds',
      label: '站点',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [],
    },
    {
      key: 'shopIds',
      label: '全部店铺',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [],
    },
    {
      key: 'budgetTypes',
      label: '预算类型',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [
        {
          label: '无预算上限',
          value: 'noBudgetCap',
        },
        {
          label: '日期范围',
          value: 'dateRange',
        },
        {
          label: '每月定期',
          value: 'monthlyRecurring',
        },
      ],
    },
    {
      key: 'adTypes',
      label: '广告类型',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [
        {
          label: '商品广告',
          value: 'SPONSORED_PRODUCTS',
        },
        {
          label: '品牌广告',
          value: 'SPONSORED_BRANDS',
        },
        {
          label: '展示广告',
          value: 'SPONSORED_DISPLAY',
        },
      ],
    },
    {
      key: 'portfoliosStates',
      label: '状态',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [
        {
          label: '投放中',
          value: 'ENABLED',
        },
        {
          label: '已暂停',
          value: 'PAUSED',
        },
        {
          label: '已归档',
          value: 'ARCHIVED',
        },
      ],
    },
    {
      key: 'states',
      label: '状态',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [
        {
          label: '投放中',
          value: 'ENABLED',
        },
        {
          label: '已暂停',
          value: 'PAUSED',
        },
        {
          label: '已归档',
          value: 'ARCHIVED',
        },
      ],
    },
    {
      key: 'portfolioIds',
      label: '广告组合',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [],
    },
    {
      type: 'input_keyword',
      key: 'portfolioName',
      keyItems: [
        { label: '组合名称', value: 'portfolioName' },
        { label: '组合ID', value: 'portfolioId' },
      ],
      keyWidth: '100',
      value: ref(),
      placeholder: '请输入',
      label: '',
      width: 160,
      isMultiple: false,
    },
    {
      type: 'input_keyword',
      key: 'campaignName',
      keyItems: [
        { label: '广告活动名称', value: 'campaignName' },
        { label: '广告活动ID', value: 'campaignId' },
      ],
      keyWidth: '140',
      value: ref(),
      placeholder: '请输入',
      label: '',
      width: 160,
      isMultiple: false,
    },
    {
      key: 'ownerIds',
      label: '销售员',
      value: ref(),
      type: 'select_multiple',
      width: 120,
      optionItems: [],
    },
    {
      key: 'date',
      label: '日期',
      value: ref(advertStore.currentSearchTime),
      type: 'date_range',
      width: 240,
      attrs: {
        placeholder: ['开始日期', '结束日期'],
      },
    },
    {
      key: 'dynamicBudgetStrategy',
      label: '竞价策略',
      value: ref(),
      type: 'select',
      width: 120,
      optionItems: [
        {
          label: '动态竞价-仅降低',
          value: 'LEGACY_FOR_SALES',
        },
        {
          label: '动态竞价-提高和降低',
          value: 'AUTO_FOR_SALES',
        },
        {
          label: '固定竞价',
          value: 'MANUAL',
        },
      ],
    },
  ])
  // 根据tabs显示对应的查询
  function getFilterItem() {
    let keys: Array<string> = []
    if (activeTab.value == 'portfolio') {
      keys = ['marketplaceIds', 'shopIds', 'budgetTypes', 'portfoliosStates', 'portfolioName', 'portfolioId', 'ownerIds', 'date']
    } else if (activeTab.value == 'campaign') {
      keys = ['marketplaceIds', 'shopIds', 'adTypes', 'states', 'portfolioIds', 'ownerIds', 'campaignName', 'campaignId', 'dynamicBudgetStrategy', 'date']
    }
    return allfilterItem.value.filter((el: any) => keys.indexOf(el.key) > -1)
  }
  //禁用时间
  function disabledDate(current) {
    return dayjs(current).isAfter(dayjs().subtract(1, 'day'))
  }
  // 获取站点
  async function getMarketList() {
    const res: any = await getShopMarketAll()
    markedtList.value = res?.data || []
    allfilterItem.value[0].optionItems = res?.data?.map((el: any) => {
      return {
        label: el.marketplaceName,
        value: el.marketplaceId,
      }
    })
  }
  // 获取店铺
  async function getShopList() {
    await useBaseData.getShopList()
    shopList.value = useBaseData.shopList
    allfilterItem.value[1].optionItems = useBaseData.shopList?.map((el: any) => {
      return {
        label: el.shopName,
        value: el.id,
      }
    })
  }
  // 获取所有用户列表
  async function getUserList() {
    const res: any = await getOrganizesUser({
      pageNum: 1,
      pageSize: 1000,
    })
    userList.value = res?.data?.records || []
    allfilterItem.value[9].optionItems = userList.value?.map((el: any) => {
      return {
        label: el.userName,
        value: el.id,
      }
    })
  }
  // 切换tabs
  function changeActiveTab(tab: string) {
    activeTab.value = tab
    allfilterItem.value[1].value = advertStore?.currentSearchVal?.shopIds || allfilterItem.value[1].value
    if (activeTab.value == 'campaign' || activeTab.value == 'portfolio') {
      allfilterItem.value[10].value = advertStore.currentSearchTime
      advertStore.currentSearchTime
      setSearchVal()
    }
  }
  // 广告组进入广告活动
  function toCampaign(row: any) {
    activeTab.value = 'campaign'
    filterItem.value.forEach((el: any) => {
      if (el.key == 'portfolioIds') el.value = [row]
    })
    changeActiveTab('campaign')
  }
  function searchKeyword(searchVal: any, item: any) {
    item.key = searchVal.code
    item.label = searchVal.label
    item.value = searchVal.value
    setSearchVal(searchVal)
  }
  // 批量选择数据
  function selectMulVal(searchVal: any, item: any) {
    item.value = searchVal
    setSearchVal()
  }
  function setSearchVal(orginVal: any = {}) {
    setResultTags()
    searchParam.value = {}
    filterItem.value.forEach((el: FilterTableItem) => {
      if (el.key == 'date') {
        searchParam.value.startDate = el.value?.[0]
        searchParam.value.endDate = el.value?.[1]
        advertStore.changeSearchTime([searchParam.value.startDate, searchParam.value.endDate])
      } else if (el.key === 'portfolioIds' && el.value instanceof Array) {
        searchParam.value.portfolioIds = el.value.map((el: any) => el.portfolioId)
      } else {
        searchParam.value[el.key] = el.value
      }
    })
    if (metricsSearchesReault.value.length) {
      searchParam.value['extendMetricsSearches'] = metricsSearchesReault.value
    }
    advertStore?.changeSearchVal(searchParam.value)

    startSearch()
  }
  function startSearch() {
    if (!searchParam.value.startDate) return
    nextTick(() => {
      if (activeTab.value == 'campaign') {
        campaignTableRef.value.getTableListByVal()
      } else {
        portfolioTableRef.value.getTableListByVal()
      }
      adChartRef.value.refreshData()
    })
  }
  function setResultTags() {
    resultTags.value = []
    filterItem.value.forEach((el: FilterTableItem) => {
      let val: any = el.value
      let noVal = val === '' || val === null || val === undefined || (val instanceof Array && val.length === 0)
      if (!noVal) {
        resultTags.value.push({
          ...el,
          tagVal: getTagVal(el),
        })
      }
    })
  }
  // 获取查过结果显示的值
  function getTagVal(item: FilterTableItem) {
    if (item.key === 'portfolioIds' && item.value instanceof Array) {
      return item.value.map((el: any) => el.portfolioName)
    } else if (item.value instanceof Array) {
      return item.value.map((str: string) => {
        return enumVal(item.optionItems, item.optionField, str)
      })
    } else {
      return enumVal(item.optionItems, item.optionField, item.value)
    }
  }
  function enumVal(optionItems: any, optionField: any, str: any) {
    if (!optionItems?.length) return str
    let option = optionItems?.find((e: any) => str == e.value)
    return option?.label || str
  }
  function resetAll() {
    filterItem.value.forEach((el: FilterTableItem) => {
      if (el.key == 'date') {
        el.value = ref(getStartAndEndTime('last_30_days'))
      } else {
        el.value = ref()
      }
    })
    metricsSearchesReault.value = []
    setSearchVal()
  }
  function delTag(data: any, type: number) {
    if (type == 1) {
      let index = filterItem.value.findIndex((el: FilterTableItem) => el.key == data.key)
      filterItem.value[index].value = ref()
    } else {
      let index = metricsSearchesReault.value.findIndex((el: any) => el.field == data.field)
      metricsSearchesReault.value.splice(index, 1)
    }
    setSearchVal()
  }
  // 获取其他指标的查询参数
  function setTargetFilter() {
    metricsSearchesReault.value = extendMetricsSearches.value.filter((el: any) => el.maxValue || el.maxValue === 0 || el.minValue || el.minValue === 0)
    setSearchVal()
    closePopover()
  }
  function closePopover() {
    selectMulRef.value.handlePopupVisibleChange(false)
  }
  function popupVisibleChange(status: boolean) {
    if (status) {
      extendMetricsSearches.value.forEach((el: any) => {
        let currentItem = metricsSearchesReault.value.find((item: any) => item.field == el.field)
        el.minValue = currentItem?.minValue
        el.maxValue = currentItem?.maxValue
      })
    }
  }
</script>
<style lang="less" scoped>
  .arco-tabs {
    background-color: #fff;
  }
  .filter-item {
    margin-right: 8px;
    margin-bottom: 5px;
  }
  .filter-result {
    margin-bottom: 5px;
  }
  .filter-list {
    flex-wrap: wrap;
  }
  .target-filter-w {
    li {
      margin-bottom: 10px;
    }
    .label {
      font-size: 12px;
      color: #888;
      width: 90px;
      text-align: right;
    }
    .unit {
      font-size: 12px;
    }
    .line {
      margin: 0 8px;
      color: #999;
    }
    :deep(.arco-input-suffix) {
      padding: 0;
    }
  }
  .arco-scrollbar {
    flex: 1;
    overflow-y: hidden;
    margin-top: 5px;
  }
  .error-w {
    flex: 1;
    background-color: #fff;
    margin-top: 10px;
  }
</style>
